<?php

class LoremIpsum {

	private $words, $wordsPerParagraph, $wordsPerSentence;

	function __construct($wordsPer = 100) {
		$this->wordsPerParagraph = $wordsPer;
		$this->wordsPerSentence = 24.460;
		$this->words = array(
			'lorem',
			'ipsum',
			'dolor',
			'sit',
			'amet',
			'consectetur',
			'adipiscing',
			'elit',
			'curabitur',
			'vel',
			'hendrerit',
			'libero',
			'eleifend',
			'blandit',
			'nunc',
			'ornare',
			'odio',
			'ut',
			'orci',
			'gravida',
			'imperdiet',
			'nullam',
			'purus',
			'lacinia',
			'a',
			'pretium',
			'quis',
			'congue',
			'praesent',
			'sagittis',
			'laoreet',
			'auctor',
			'mauris',
			'non',
			'velit',
			'eros',
			'dictum',
			'proin',
			'accumsan',
			'sapien',
			'nec',
			'massa',
			'volutpat',
			'venenatis',
			'sed',
			'eu',
			'molestie',
			'lacus',
			'quisque',
			'porttitor',
			'ligula',
			'dui',
			'mollis',
			'tempus',
			'at',
			'magna',
			'vestibulum',
			'turpis',
			'ac',
			'diam',
			'tincidunt',
			'id',
			'condimentum',
			'enim',
			'sodales',
			'in',
			'hac',
			'habitasse',
			'platea',
			'dictumst',
			'aenean',
			'neque',
			'fusce',
			'augue',
			'leo',
			'eget',
			'semper',
			'mattis',
			'tortor',
			'scelerisque',
			'nulla',
			'interdum',
			'tellus',
			'malesuada',
			'rhoncus',
			'porta',
			'sem',
			'aliquet',
			'et',
			'nam',
			'suspendisse',
			'potenti',
			'vivamus',
			'luctus',
			'fringilla',
			'erat',
			'donec',
			'justo',
			'vehicula',
			'ultricies',
			'varius',
			'ante',
			'primis',
			'faucibus',
			'ultrices',
			'posuere',
			'cubilia',
			'curae',
			'etiam',
			'cursus',
			'aliquam',
			'quam',
			'dapibus',
			'nisl',
			'feugiat',
			'egestas',
			'class',
			'aptent',
			'taciti',
			'sociosqu',
			'ad',
			'litora',
			'torquent',
			'per',
			'conubia',
			'nostra',
			'inceptos',
			'himenaeos',
			'phasellus',
			'nibh',
			'pulvinar',
			'vitae',
			'urna',
			'iaculis',
			'lobortis',
			'nisi',
			'viverra',
			'arcu',
			'morbi',
			'pellentesque',
			'metus',
			'commodo',
			'ut',
			'facilisis',
			'felis',
			'tristique',
			'ullamcorper',
			'placerat',
			'aenean',
			'convallis',
			'sollicitudin',
			'integer',
			'rutrum',
			'duis',
			'est',
			'etiam',
			'bibendum',
			'donec',
			'pharetra',
			'vulputate',
			'maecenas',
			'mi',
			'fermentum',
			'consequat',
			'suscipit',
			'aliquam',
			'habitant',
			'senectus',
			'netus',
			'fames',
			'quisque',
			'euismod',
			'curabitur',
			'lectus',
			'elementum',
			'tempor',
			'risus',
			'cras');
	}

	function getContent($count, $format = 'html', $loremipsum = true) {
		$format = strtolower($format);

		if ($count <= 0)
			return '';

		switch ($format) {
			case 'txt':
				return $this->getText($count, $loremipsum);
			case 'plain':
				return $this->getPlain($count, $loremipsum);
			default:
				return $this->getHTML($count, $loremipsum);
		}
	}

	private function getWords(&$arr, $count, $loremipsum) {
		$i = 0;
		if ($loremipsum) {
			$i = 2;
			$arr[0] = 'lorem';
			$arr[1] = 'ipsum';
		}

		for ($i; $i < $count; $i++) {
			$index = array_rand($this->words);
			$word = $this->words[$index];
			//echo $index . '=>' . $word . '<br />';

			if ($i > 0 && $arr[$i - 1] == $word)
				$i--;
			else
				$arr[$i] = $word;
		}
	}

	private function getPlain($count, $loremipsum, $returnStr = true) {
		$words = array();
		$this->getWords($words, $count, $loremipsum);
		//print_r($words);

		$delta = $count;
		$curr = 0;
		$sentences = array();
		while ($delta > 0) {
			$senSize = $this->gaussianSentence();
			//echo $curr . '<br />';
			if (($delta - $senSize) < 4)
				$senSize = $delta;

			$delta -= $senSize;

			$sentence = array();
			for ($i = $curr; $i < ($curr + $senSize); $i++)
				$sentence[] = $words[$i];

			$this->punctuate($sentence);
			$curr = $curr + $senSize;
			$sentences[] = $sentence;
		}

		if ($returnStr) {
			$output = '';
			foreach ($sentences as $s)
				foreach ($s as $w)
					$output .= $w . ' ';

			return $output;
		}
		else
			return $sentences;
	}

	private function getText($count, $loremipsum) {
		$sentences = $this->getPlain($count, $loremipsum, false);
		$paragraphs = $this->getParagraphArr($sentences);

		$paragraphStr = array();
		foreach ($paragraphs as $p) {
			$paragraphStr[] = $this->paragraphToString($p);
		}

		$paragraphStr[0] = "\t" . $paragraphStr[0];
		return implode("\n\n\t", $paragraphStr);
	}

	private function getParagraphArr($sentences) {
		$wordsPer = $this->wordsPerParagraph;
		$sentenceAvg = $this->wordsPerSentence;
		$total = count($sentences);

		$paragraphs = array();
		$pCount = 0;
		$currCount = 0;
		$curr = array();

		for ($i = 0; $i < $total; $i++) {
			$s = $sentences[$i];
			$currCount += count($s);
			$curr[] = $s;
			if ($currCount >= ($wordsPer - round($sentenceAvg / 2.00)) || $i == $total - 1) {
				$currCount = 0;
				$paragraphs[] = $curr;
				$curr = array();
				//print_r($paragraphs);
			}
			//print_r($paragraphs);
		}

		return $paragraphs;
	}

	private function getHTML($count, $loremipsum) {
		$sentences = $this->getPlain($count, $loremipsum, false);
		$paragraphs = $this->getParagraphArr($sentences);
		//print_r($paragraphs);

		$paragraphStr = array();
		foreach ($paragraphs as $p) {
			$paragraphStr[] = "<p>\n" . $this->paragraphToString($p, true) . '</p>';
		}

		//add new lines for the sake of clean code
		return implode("\n", $paragraphStr);
	}

	private function paragraphToString($paragraph, $htmlCleanCode = false) {
		$paragraphStr = '';
		foreach ($paragraph as $sentence) {
			foreach ($sentence as $word)
				$paragraphStr .= $word . ' ';

			if ($htmlCleanCode)
				$paragraphStr .= "\n";
		}
		return $paragraphStr;
	}

	/*
	 * Inserts commas and periods in the given
	 * word array.
	 */

	private function punctuate(& $sentence) {
		$count = count($sentence);
		$sentence[$count - 1] = $sentence[$count - 1] . '.';

		if ($count < 4)
			return $sentence;

		$commas = $this->numberOfCommas($count);

		for ($i = 1; $i <= $commas; $i++) {
			$index = (int) round($i * $count / ($commas + 1));

			if ($index < ($count - 1) && $index > 0) {
				$sentence[$index] = $sentence[$index] . ',';
			}
		}
	}

	/*
	 * Determines the number of commas for a
	 * sentence of the given length. Average and
	 * standard deviation are determined superficially
	 */

	private function numberOfCommas($len) {
		$avg = (float) log($len, 6);
		$stdDev = (float) $avg / 6.000;

		return (int) round($this->gauss_ms($avg, $stdDev));
	}

	/*
	 * Returns a number on a gaussian distribution
	 * based on the average word length of an english
	 * sentence.
	 * Statistics Source:
	 * 	http://hearle.nahoo.net/Academic/Maths/Sentence.html
	 * 	Average: 24.46
	 * 	Standard Deviation: 5.08
	 */

	private function gaussianSentence() {
		$avg = (float) 24.460;
		$stdDev = (float) 5.080;

		return (int) round($this->gauss_ms($avg, $stdDev));
	}

	/*
	 * The following three functions are used to
	 * compute numbers with a guassian distrobution
	 * Source:
	 * 	http://us.php.net/manual/en/function.rand.php#53784
	 */

	private function gauss() {   // N(0,1)
		// returns random number with normal distribution:
		//   mean=0
		//   std dev=1
		// auxilary vars
		$x = $this->random_0_1();
		$y = $this->random_0_1();

		// two independent variables with normal distribution N(0,1)
		$u = sqrt(-2 * log($x)) * cos(2 * pi() * $y);
		$v = sqrt(-2 * log($x)) * sin(2 * pi() * $y);

		// i will return only one, couse only one needed
		return $u;
	}

	private function gauss_ms($m = 0.0, $s = 1.0) {
		return $this->gauss() * $s + $m;
	}

	private function random_0_1() {
		return (float) rand() / (float) getrandmax();
	}

}

?>